package crypot

import (
	"crypto/md5"
	"crypto/sha1"
	"encoding/base64"
	"encoding/binary"
	"encoding/hex"
	"github.com/gogf/gf/crypto/gaes"
	"github.com/gogf/gf/crypto/gdes"
	"appService/src/global"
	"time"
)

//密码加密函数
func PassWordEncryption(pass string) string {
	pass = global.EncryptionString + pass + global.EncryptionString
	return Md5String(pass)
}

//MD5加密
func Md5String(str string) string {
	m := md5.New()
	m.Write([]byte(str))
	return hex.EncodeToString(m.Sum(nil))
}

//sha1加密
func Sha1Hex(str string) string {
	sh := sha1.New()
	sh.Write([]byte(str))
	return hex.EncodeToString(sh.Sum([]byte("")))
}

//DES加密,base64加密
func DESEncrypt(str string) (string, error) {
	iv := []byte{25, 45, 78, 97, 125, 65, 49, 112}
	res, err := gdes.EncryptCBC([]byte(str), []byte(global.DESKey), iv, gdes.PKCS5PADDING)
	if err == nil {
		return base64.StdEncoding.EncodeToString(res), nil
	}
	return "", err
}

//base64解密，DES解密
func DESDecrypt(str string) (string, error) {
	iv := []byte{25, 45, 78, 97, 125, 65, 49, 112}
	decodeBytes, err := base64.StdEncoding.DecodeString(str)
	if err == nil {
		res, err := gdes.DecryptCBC(decodeBytes, []byte(global.DESKey), iv, gdes.PKCS5PADDING)
		if err == nil {
			return string(res), nil
		}
	}
	return "", err
}

//AES加密,base64加密
func AESEncrypt(str string) (string, error) {
	iv := []byte{0x5F, 0xAF, 0x9F, 0x1A, 0x44, 0x4E, 0x36, 0x89, 0xA4, 0xD3, 0x7A, 0xCB, 0xFC, 0x8F, 0xE8, 0xF2}
	strByte := []byte(str)
	EnByte := make([]byte, 8)
	timeStamp := time.Now().Unix() + global.TokenExpiresAt
	binary.BigEndian.PutUint64(EnByte, uint64(timeStamp))
	EnByte = append(EnByte, strByte...)
	byteStr, err := gaes.EncryptCBC(EnByte, []byte(global.AESKey), iv)
	if err == nil {
		return base64.StdEncoding.EncodeToString(byteStr), nil
	}
	return "", err
}

//返回：解码后的数据，是否有效，错误信息
//：：base64解密，AES解密
func AESDecrypt(str string, checkTime bool) (string, bool, error) {
	iv := []byte{0x5F, 0xAF, 0x9F, 0x1A, 0x44, 0x4E, 0x36, 0x89, 0xA4, 0xD3, 0x7A, 0xCB, 0xFC, 0x8F, 0xE8, 0xF2}
	decodeBytes, err := base64.StdEncoding.DecodeString(str)
	if err == nil {
		dst, err := gaes.DecryptCBC(decodeBytes, []byte(global.AESKey), iv)
		if checkTime && len(dst) > 8 {
			timeStamp :=time.Now().Unix()
			timeUnix:=int64(binary.BigEndian.Uint64(dst[:8]))
			if timeStamp > timeUnix {
				return "", false,nil
			}
		}
		if err == nil {
			return string(dst[8:]), true, nil
		}
	}
	return "", false, err
}
